package com.woniuxy.simple;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class SimpleConsumer2 {
    //当消息堆叠时：方法一：定义多个消费者监听同一个队列
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory connectionFactory=new ConnectionFactory();
        //设置连接工厂信息
        connectionFactory.setHost("127.0.0.1");//可以不设置 默认就是localhost
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        //获取连接对象
        Connection connection = connectionFactory.newConnection();
        //建立通道
        Channel channel = connection.createChannel();
        //消费者是一直运行着的    autoAck:true 自动提交
        channel.basicConsume("simple1",false,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者接收到来自：SimpleProducer的消息:"+new String(body));
                //消息确定机制：需要提交确定信息给队列，要不然队列里面的消息会一直存在，当消费者启动时会继续发给消费者，消费者确定消息后，队列会删除对应的消息

                new Thread(){
                    @Override
                    public void run() {
                        System.out.println("子线程异步消费");
                        //当消息堆叠时：方法二：开辟线程池，异步消费，比如：开辟一个子进程去完成消费业务，缺点是：如果子进程报错，但是主进程并不会知道，如果使用自动提交，依然会将确定消息提交，导致数据丢失，需要手动提交

                        try {
                            //int a=10/0;
                            System.out.println("子线程异步消费完成");
                            channel.basicAck(envelope.getDeliveryTag(),true);
                        } catch (Exception e) {
                            e.printStackTrace();
                            System.out.println("子线程异步消费出错");
                            try {
                                channel.basicNack(envelope.getDeliveryTag(),true,true);
                            } catch (IOException ex) {
                                ex.printStackTrace();
                            }
                        }

                    }
                }.start();

                //手动提交 true表示 确定编号小于接收到的消息编号的全部消息 false 表示确定当前消息
               // channel.basicAck(envelope.getDeliveryTag(),true);
                System.out.println("消费者处理业务");
            }
        });

    }
}
